use std::fs;
use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
// use std::os::unix;
use std::path::Path;
// std::io::fs模块包含几个处理文件系统的函数
// `% cat path`的简单实现
fn cat(path: &Path) -> io::Result<String> {
    let mut f = File::open(path)?;
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}
// `% echo s > path`的简单实现
fn echo(s: &str, path: &Path) -> io::Result<()> {
    let mut f = File::create(path)?;
    f.write_all(s.as_bytes())
}

// `% touch path`的简单实现（忽略已存在的文件)
fn touch(path: &Path) -> io::Result<()> {
    match OpenOptions::new().create(true).write(true).open(path) {
        Ok(_) => Ok(()),
        Err(e) => Err(e),
    }
}
// `% ls -a path`列出递归目录所有内容
fn ls(path: &Path) -> io::Result<()> {
    for entry in fs::read_dir(path)? {
        let entry = entry?;
        let path = entry.path();
        if path.is_dir() {
            println!("> {:?}", path);
            ls(&path)?;
        } else {
            println!("> {:?}", path);
        }
    }
    Ok(())
}

fn main() {
    println!("`mkdir a`");
//     创建一个目录,返回`io::Result<()>`
    match fs::create_dir("a") {
        Err(why) => println!("!{:?}",why.kind()),
        Ok(_) => {},
    }
    println!("`echo hello > a/b.txt`");
//     与前面匹配可以用`unwrap_or_else`方法简化
    echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why|println!("! {:?}", why.kind()));
    println!("`cat a/b.txt`");
//     查看`a/b.txt`内容
    match cat(&Path::new("a/b.txt")) {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(s) => println!("{}", s),
    }

    println!("`mkdir -p a/c/d`");
//     递归创建一个目录,返回`io::Result<()>`
    fs::create_dir_all("a/c/d").unwrap_or_else(|why|println!("! {:?}", why.kind()));
    println!("`ls a`");
//     列出a目录内容
    match fs::read_dir("a") {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(paths) => for path in paths {
            println!("> {:?}", path.unwrap().path());
        },
    }
    println!("`touch a/c/d/e.txt`");
//     在d目录下创建一个空文件
    touch(&Path::new("a/c/d/e.txt")).unwrap_or_else(|why|println!("! {:?}", why.kind()));
    println!("`ls -a a`");
//     列出a目录及递归目录与文件的内容
    ls(&Path::new("a")).unwrap_or_else(|why|println!("! {:?}", why.kind()));

//     删除操作
    println!("`rm a/b.txt`");
//     删除一个文件
    fs::remove_file("a/b.txt").unwrap_or_else(|why|println!("! {:?}", why.kind()));
    // println!("`rm /a/b.txt`已删除");
    println!("`rmdir a/c/d");
//     删除空目录
    fs::remove_dir("a/c/d").unwrap_or_else(|why|println!("! {:?}", why.kind()));
    println!("`rm -fr a`");
//     递归删除目录及目录下的所有内容
    fs::remove_dir_all("a").unwrap_or_else(|why|println!("! {:?}", why.kind()));
    println!("a递归目录已删除");
//     在linux下创建符号连接
//     println!("`ln -s /etc/resolv.conf resolv`");
    #[cfg(all(not(target_os = "hermit"), any(unix, doc)))]
    if cfg!(target_family = "unix") {
        unix::fs::symlink("/etc/resolv.conf", "resolv").unwrap_or_else(|why|println!("! {:?}", why.kind()));
    }
}



